package com.wangxin.study8.threadtest;

import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CyclicBarrier;

/**
 * @author jojo.wang
 * @title: CyclicBarrierTest
 * @projectName study8
 * @description: CyclicBarrier使用
 * 用来控制多个线程互相等待，只有当多个线程都到达时，这些线程才会继续执行。
 * 和 CountdownLatch 相似，都是通过维护计数器来实现的。线程执行 await() 方法之后计数器会减 1，并进行等待，直到计数器为 0，所有调用 await() 方法而在等待的线程才能继续执行。
 * CyclicBarrier 和 CountdownLatch 的一个区别是，CyclicBarrier 的计数器通过调用 reset() 方法可以循环使用，所以它才叫做循环屏障。
 * CyclicBarrier 有两个构造函数，其中 parties 指示计数器的初始值，barrierAction 在所有线程都到达屏障的时候会执行一次。
 * @date 2019/5/617:35
 */
public class CyclicBarrierActionTest {
    public static volatile CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<>();

    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(6,()->{
            System.out.println("action:"+copyOnWriteArrayList.toString());
        });
        for (int i = 0; i < 3; i++) {
            Thread thread1 = new Thread(new Thread1(cyclicBarrier,i));
            Thread thread2 = new Thread(new Thread2(cyclicBarrier,i));
            thread1.start();
            thread2.start();
        }
    }


}
class Thread1 implements Runnable{
    private CyclicBarrier cyclicBarrier;
    private int num;
    public Thread1(CyclicBarrier cyclicBarrier,int num){
        this.cyclicBarrier = cyclicBarrier;
        this.num = num;
    }
    @Override
    public void run() {
        System.out.println("thread1 threadNum =="+num+"is ready!");
        try {
            CyclicBarrierActionTest.copyOnWriteArrayList.add("AA");
            cyclicBarrier.await();
        }catch (Exception e){
        }
        System.out.println("thread1 threadNum:"+num+"is finish!!!");
    }
}

class Thread2 implements Runnable{
    private CyclicBarrier cyclicBarrier;
    private int num;
    public Thread2(CyclicBarrier cyclicBarrier,int num){
        this.cyclicBarrier = cyclicBarrier;
        this.num = num;
    }
    @Override
    public void run() {
        System.out.println("thread2 threadNum =="+num+"is ready!");
        try {
            CyclicBarrierActionTest.copyOnWriteArrayList.add("BB");
            cyclicBarrier.await();
        }catch (Exception e){

        }
        System.out.println("thread2 threadNum:"+num+"is finish!!!");
    }
}